package com.water76016.ourtask.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * @program: our-task
 * @description: redis操作服务类
 * @author: water76016
 * @create: 2020-09-24 16:45
 **/
@Component
public class RedisUtils {

        /**
         * 由于没有指定具体类型<String, Object>，用Resource注入才有效
         * */
        @Resource
        private RedisTemplate redisTemplate;

        @Autowired(required = false)
        public void setRedisTemplate(RedisTemplate redisTemplate) {
                RedisSerializer stringSerializer = new StringRedisSerializer();
                redisTemplate.setKeySerializer(stringSerializer);
                redisTemplate.setValueSerializer(stringSerializer);
                redisTemplate.setHashKeySerializer(stringSerializer);
                redisTemplate.setHashValueSerializer(stringSerializer);
                this.redisTemplate = redisTemplate;
        }

        /**
         * 保存属性
         *
         * @param key   the key
         * @param value the value
         * @param time  the time
         */
        public void set(String key, Object value, long time) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        }

        /**
         * 保存属性
         *
         * @param key   键
         * @param value 值
         */
        public void set(String key, Object value) {

                redisTemplate.opsForValue().set(key, value);
        }

        /**
         * 获取属性
         *
         * @param key the key
         * @return the object
         */
        public Object get(String key) {
                return redisTemplate.opsForValue().get(key);
        }

        /**
         * 删除属性
         *
         * @param key the key
         * @return the boolean
         */
        public Boolean del(String key) {
                return redisTemplate.delete(key);
        }

        /**
         * 批量删除属性
         *
         * @param keys the keys
         * @return the long
         */
        public Long del(List<String> keys) {
                return redisTemplate.delete(keys);
        }

        /**
         * 设置过期时间
         *
         * @param key  the key
         * @param time the time
         * @return the boolean
         */
        public Boolean expire(String key, long time) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
        }

        /**
         * 获取过期时间
         *
         * @param key the key
         * @return the expire
         */
        public Long getExpire(String key) {
                return redisTemplate.getExpire(key, TimeUnit.SECONDS);
        }

        /**
         * 判断是否有该属性
         *
         * @param key the key
         * @return the boolean
         */
        public Boolean hasKey(String key) {
                return redisTemplate.hasKey(key);
        }

        /**
         * 按delta递增
         *
         * @param key   the key
         * @param delta the delta
         * @return the long
         */
        public Long incr(String key, long delta) {
                return redisTemplate.opsForValue().increment(key, delta);
        }

        /**
         * 按delta递减
         *
         * @param key   the key
         * @param delta the delta
         * @return the long
         */
        public Long decr(String key, long delta) {
                return redisTemplate.opsForValue().increment(key, -delta);
        }

        /**
         * 获取Hash结构中的属性
         *
         * @param key     the key
         * @param hashKey the hash key
         * @return the object
         */
        public Object hGet(String key, String hashKey) {
                return redisTemplate.opsForHash().get(key, hashKey);
        }

        /**
         * 向Hash结构中放入一个属性
         *
         * @param key     the key
         * @param hashKey the hash key
         * @param value   the value
         * @param time    the time
         * @return the boolean
         */
        public Boolean hSet(String key, String hashKey, Object value, long time) {
                redisTemplate.opsForHash().put(key, hashKey, value);
                return expire(key, time);
        }

        /**
         * 向Hash结构中放入一个属性
         *
         * @param key     the key
         * @param hashKey the hash key
         * @param value   the value
         */
        public void hSet(String key, String hashKey, Object value) {
                redisTemplate.opsForHash().put(key, hashKey, value);
        }

        /**
         * 直接获取整个Hash结构
         *
         * @param key the key
         * @return the map
         */
        public Map<Object, Object> hGetAll(String key) {
                return redisTemplate.opsForHash().entries(key);
        }

        /**
         * 直接设置整个Hash结构
         *
         * @param key  the key
         * @param map  the map
         * @param time the time
         * @return the boolean
         */
        public Boolean hSetAll(String key, Map<String, Object> map, long time) {
                redisTemplate.opsForHash().putAll(key, map);
                return expire(key, time);
        }

        /**
         * 直接设置整个Hash结构
         *
         * @param key the key
         * @param map the map
         */
        public void hSetAll(String key, Map<String, Object> map) {
                redisTemplate.opsForHash().putAll(key, map);
        }

        /**
         * 删除Hash结构中的属性
         *
         * @param key     the key
         * @param hashKey the hash key
         */
        public void hDel(String key, Object... hashKey) {
                redisTemplate.opsForHash().delete(key, hashKey);
        }

        /**
         * 判断Hash结构中是否有该属性
         *
         * @param key     the key
         * @param hashKey the hash key
         * @return the boolean
         */
        public Boolean hHasKey(String key, String hashKey) {
                return redisTemplate.opsForHash().hasKey(key, hashKey);
        }

        /**
         * Hash结构中属性递增
         *
         * @param key     the key
         * @param hashKey the hash key
         * @param delta   the delta
         * @return the long
         */
        public Long hIncr(String key, String hashKey, Long delta) {
                return redisTemplate.opsForHash().increment(key, hashKey, delta);
        }

        /**
         * Hash结构中属性递减
         *
         * @param key     the key
         * @param hashKey the hash key
         * @param delta   the delta
         * @return the long
         */
        public Long hDecr(String key, String hashKey, Long delta) {
                return redisTemplate.opsForHash().increment(key, hashKey, -delta);
        }

        /**
         * 获取Set结构
         *
         * @param key the key
         * @return the set
         */
        public Set<Object> sMembers(String key) {
                return redisTemplate.opsForSet().members(key);
        }

        /**
         * 向Set结构中添加属性
         *
         * @param key    the key
         * @param values the values
         * @return the long
         */
        public Long sAdd(String key, Object... values) {
                return redisTemplate.opsForSet().add(key, values);
        }

        /**
         * 向Set结构中添加属性
         *
         * @param key    the key
         * @param time   the time
         * @param values the values
         * @return the long
         */
        public Long sAdd(String key, long time, Object... values) {
                Long count = redisTemplate.opsForSet().add(key, values);
                expire(key, time);
                return count;
        }

        /**
         * 是否为Set中的属性
         *
         * @param key   the key
         * @param value the value
         * @return the boolean
         */
        public Boolean sIsMember(String key, Object value) {
                return redisTemplate.opsForSet().isMember(key, value);
        }

        /**
         * 获取Set结构的长度
         *
         * @param key the key
         * @return the long
         */
        public Long sSize(String key) {
                return redisTemplate.opsForSet().size(key);
        }

        /**
         * 删除Set结构中的属性
         *
         * @param key    the key
         * @param values the values
         * @return the long
         */
        public Long sRemove(String key, Object... values) {
                return redisTemplate.opsForSet().remove(key, values);
        }

        /**
         * 获取List结构中的属性
         *
         * @param key   the key
         * @param start the start
         * @param end   the end
         * @return the list
         */
        public List<Object> lRange(String key, long start, long end) {
                return redisTemplate.opsForList().range(key, start, end);
        }

        /**
         * 获取List结构的长度
         *
         * @param key the key
         * @return the long
         */
        public Long lSize(String key) {
                return redisTemplate.opsForList().size(key);
        }

        /**
         * 根据索引获取List中的属性
         *
         * @param key   the key
         * @param index the index
         * @return the object
         */
        public Object lIndex(String key, long index) {
                return redisTemplate.opsForList().index(key, index);
        }

        /**
         * 向List结构中添加属性
         *
         * @param key   the key
         * @param value the value
         * @return the long
         */
        public Long lPush(String key, Object value) {
                return redisTemplate.opsForList().rightPush(key, value);
        }

        /**
         * 向List结构中添加属性
         *
         * @param key   the key
         * @param value the value
         * @param time  the time
         * @return the long
         */
        public Long lPush(String key, Object value, long time) {
                Long index = redisTemplate.opsForList().rightPush(key, value);
                expire(key, time);
                return index;
        }

        /**
         * 向List结构中批量添加属性
         *
         * @param key    the key
         * @param values the values
         * @return the long
         */
        public Long lPushAll(String key, Object... values) {
                return redisTemplate.opsForList().rightPushAll(key, values);
        }

        /**
         * 向List结构中批量添加属性
         *
         * @param key    the key
         * @param time   the time
         * @param values the values
         * @return the long
         */
        public Long lPushAll(String key, Long time, Object... values) {
                Long count = redisTemplate.opsForList().rightPushAll(key, values);
                expire(key, time);
                return count;
        }

        /**
         * 从List结构中移除属性
         *
         * @param key   the key
         * @param count the count
         * @param value the value
         * @return the long
         */
        public Long lRemove(String key, long count, Object value) {
                return redisTemplate.opsForList().remove(key, count, value);
        }
}
